package arr;

import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;

/**
 * 动态数组
 *
 * @author yyz
 * @create 2023-11-09 16:42
 */
public class DynamicArray implements Iterable<Integer> {
    private int[] array;
    private int capacity = 8;
    private int size = 0;

    /**
     * 添加元素
     *
     * @param element 需要添加的元素
     */
    public void add(int element) {
        checkCapacity();
        array[size] = element;
        size++;
    }

    /**
     * 插入元素
     *
     * @param index   插入元素的索引
     * @param element 插入的元素
     */
    public boolean insert(int index, int element) {
        checkCapacity();
        if (!(index < size && index >= 0)) {
            return false;
        }
        System.arraycopy(array, index, array,
                index + 1, size - index);
        array[index] = element;
        size++;
        return true;
    }

    /**
     * 删除元素
     *
     * @param index 删除元素的索引
     * @return 删除成功返回删除的元素，删除失败返回-1
     */
    public int remove(int index) {
        if (!(index < size && index >= 0)) {
            return -1;
        }
        int removeEle = array[index];
        if (index != size - 1) {
            System.arraycopy(array, index + 1, array,
                    index, size - index - 1);
        }
        size--;
        return removeEle;
    }

    /**
     * 遍历方法1 -函数遍历
     *
     * @param consumer 遍历要执行的操作, 入参: 每个元素
     */
    public void foreach(Consumer<Integer> consumer) {
        for (int i = 0; i < size; i++) {
            consumer.accept(array[i]);
        }
    }


    /**
     * 遍历方法2 -迭代器遍历
     */
    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<>() {
            int i = 0;

            @Override
            public boolean hasNext() {
                return i < size;
            }

            @Override
            public Integer next() {
                return array[i++];
            }
        };
    }

    /**
     * 遍历方法3 - stream 遍历
     *
     * @return stream 流
     */
    public IntStream stream() {
        return IntStream.of(Arrays.copyOfRange(array, 0, size));
    }

    /**
     * 判断容量
     */
    private void checkCapacity() {
        if (size == 0) {
            array = new int[capacity];
        } else if (size == capacity) {
            capacity += capacity >> 1;
            int[] newArr = new int[capacity];
            System.arraycopy(array, 0,
                    newArr, 0, size);
            array = newArr;
        }
    }
}
